The present invention generally relates to techniques for recovering from fatal errors encountered in executing computer program code, and more particularly to compilation techniques for addressing the possibility of fatal software errors.
Certain types of software errors are fatal to program execution. For example, a reference to a memory address that is beyond the address domain of a program will likely result in a fatal error. Certain timing or other transient conditions may also trigger fatal errors.
While certain errors may be within the control of the software developer, the developer may be unable to guard against certain other errors in developing the software. Though rare, there is a possibility that certain other errors may be introduced in the compilation of the source code. Since the software developer assumes that a compiler will not introduce errors, the developer will have limited opportunity to identify and limited insight into compiler-introduced errors.
Some compilers include an optimization phase for producing code that is fast and small. Code can be optimized in a variety of situations. For example, commonly used sub-expressions may be identified and code generated to evaluate the sub-expression once rather than generating code that repeatedly evaluates the same sub-expression. In another example, a repeated address calculation can be identified and code generated to calculate the address once.
Programming loops are also candidates for optimization. An example optimization of a programming loop is to move loop invariants from within the loop to outside the loop. A loop invariant is a computation that produces the same result in each iteration. By moving a loop invariant to a point in the program just before the loop is entered, the computation is performed once rather than repeatedly in the loop.
While it is a clear objective that any compiler-based code optimization not change the logic of the original source code, it is recognized that complicated optimization techniques have a greater possibility of introducing an error than do straightforward optimization techniques. In addition, optimization may expose program behavior that is potentially erroneous. For example, a program may have variables that are not initialized or asynchronously reference memory locations that have not been properly declared (i.e., volatile in C or C++). These examples may result in code that operates correctly when un-optimized, but fails when optimized.
A method and apparatus that address the aforementioned problems, as well as other related problems, are therefore desirable.
In various embodiments, methods and apparatus are provided for creating alternative versions of code segments and dynamically substituting execution of the alternative code versions. In one embodiment, a first set of object code segments are generated and optimized at a first optimization level, and a second set of object code segments are generated and optimized at a second optimization level. The second set of object code segments are respectively associated with the first object code segments. In the event that execution of the first set of segments fails, the second set of object code modules are available as alternative code segments to execute.
In another embodiment, checkpoints in the program code are identified by a compiler, and the checkpoints are used to delineate the segments of object code. In one embodiment, the first set of segments are optimized at a greater level than the second set of segments. Upon detecting a program error in executing the first set of segments, state information of the program is recovered from a checkpoint, and an object code module is selected from either the first set or second set for execution.
It will be appreciated that various other embodiments are set forth in the Detailed Description and Claims which follow.